package cn.myframe.controller.sys;

import cn.myframe.core.R;
import cn.myframe.redis.RedisService;
import cn.myframe.service.sys.SysGeneratorService;
import cn.myframe.utils.annotation.IgnoreAuth;
import cn.myframe.utils.authorize.EncryptData;
import cn.myframe.utils.authorize.HardwareUtil;
import cn.myframe.utils.authorize.HtmlUtil;
import cn.myframe.utils.core.PageUtils;
import cn.myframe.utils.core.Query;
import cn.myframe.utils.xss.XssHttpServletRequestWrapper;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代码生成器
 * 
 * @author ynz
 * @email ynz@myframe.cn
 * @date 2018年8月2日 上午8:15:00
 */
@Controller
@RequestMapping("/sys/generator")
@IgnoreAuth
public class SysGeneratorController {
	@Autowired
	private SysGeneratorService sysGeneratorService;
	@Value("${spring.datasource.url:#{null}}")
    private String dbUrl;
	@Autowired
    private RedisService redisService;
	
	/**
	 * 列表
	 */
	@ResponseBody
	@RequestMapping("/list")
	//@RequiresPermissions("sys:generator:list")
	public R list(@RequestParam Map<String, Object> params){
		//查询列表数据
		Query query = new Query(params);
		List<Map<String, Object>> list = sysGeneratorService.queryList(query);
		int total = sysGeneratorService.queryTotal(query);
		
		PageUtils pageUtil = new PageUtils(list, total, query.getLimit(), query.getPage());		
		return R.ok().put("page", pageUtil);
	}
		
	
	/**
	 * 生成代码
	 */
	@IgnoreAuth
	@RequestMapping("/code")
	//@RequiresPermissions("sys:generator:code")
	public void code(HttpServletRequest request, HttpServletResponse response) throws IOException{
		String[] tableNames = new String[]{};
		//获取表名，不进行xss过滤
		HttpServletRequest orgRequest = XssHttpServletRequestWrapper.getOrgRequest(request);
		String tables = orgRequest.getParameter("tables");
		//tableNames = JSON.parseArray(tables).toArray(tableNames);
		tableNames = tables.split(",");
		String dbType = null;
		if(dbUrl.startsWith("jdbc:mysql")){
			dbType = "mysql";
		}else if(dbUrl.startsWith("jdbc:oracle")){
			dbType = "oracle";
		}	
		byte[] data = sysGeneratorService.generatorCode(tableNames,dbType);
		
		response.reset();  
        response.setHeader("Content-Disposition", "attachment; filename=\"myframe.zip\"");
        response.addHeader("Content-Length", "" + data.length);  
        response.setContentType("application/octet-stream; charset=UTF-8");  
        
        IOUtils.write(data, response.getOutputStream());  
	}
	
	//保存编辑后列数据
	static Map<String,List<Map<String,String>>> TABLE_COLUMNS = null;
	/**
	 * 生成代码
	 */
	@IgnoreAuth
	@RequestMapping("/setColumns")
	@ResponseBody
	//@RequiresPermissions("sys:generator:code")
	public R setColumns(@RequestBody List<Map<String,String>> columns,@RequestParam String tableName) throws IOException{
		if(TABLE_COLUMNS == null){
			TABLE_COLUMNS = new HashMap<>();
		}
		TABLE_COLUMNS.put(tableName, columns);
		//this.columns = tableName;
		redisService.set("setColumns",JSON.toJSONString(TABLE_COLUMNS));
		return R.ok();
	}
	
	/**
	 * 生成代码
	 */
	@IgnoreAuth
	@RequestMapping("/codeDetail")
	//@RequiresPermissions("sys:generator:code")
	public void codeDetail(HttpServletRequest request, HttpServletResponse response,@RequestParam String tableName) throws IOException{
		String[] tableNames = new String[]{};
		//获取表名，不进行xss过滤
		HttpServletRequest orgRequest = XssHttpServletRequestWrapper.getOrgRequest(request);
		//String tables = orgRequest.getParameter("tables");
		//tableNames = JSON.parseArray(tables).toArray(tableNames);
		String tables=tableName;
		tableNames = tables.split(",");
		String dbType = null;
		List<Map<String,String>> columns = TABLE_COLUMNS.get(tableName);
		if(dbUrl.startsWith("jdbc:mysql")){
			dbType = "mysql";
		}else if(dbUrl.startsWith("jdbc:oracle")){
			dbType = "oracle";
		}	
		byte[] data = sysGeneratorService.generatorCode(tableNames,dbType,columns);
		
		response.reset();  
        response.setHeader("Content-Disposition", "attachment; filename=\"myframe.zip\"");
        response.addHeader("Content-Length", "" + data.length);  
        response.setContentType("application/octet-stream; charset=UTF-8"); 
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        IOUtils.write(data, response.getOutputStream());  
	}

	@IgnoreAuth
	@RequestMapping("/createRegistFile")
	public void createRegistFile(HttpServletRequest request,HttpServletResponse response) throws IOException
	{
		String mac = HardwareUtil.getMac();
		EncryptData enc = new EncryptData();
		String registInfo = enc.encrypt("myframe" + mac);
		byte[] data = registInfo.getBytes();
		HtmlUtil.outPutFile("regist.dat", registInfo, response);
	}

	@ResponseBody
	@RequestMapping("/tableList")
	@IgnoreAuth
	public R tableList(@RequestParam Map<String, Object> params){
		List<Map<String, String>> columns = null;
		if(TABLE_COLUMNS != null&&TABLE_COLUMNS.containsKey(String.valueOf(params.get("tableName")))){
			columns = TABLE_COLUMNS.get(String.valueOf(params.get("tableName")));
		}else{
			Map<String,List<Map<String,String>>> redisMap = null;
			List<Map<String, String>> redisColumnMap = new ArrayList<>();
			if(redisService.get("setColumns")!=null){
				redisMap = (Map<String,List<Map<String,String>>>)JSON.parse(redisService.get("setColumns").toString());
				TABLE_COLUMNS = redisMap;
				if(redisMap!=null && redisMap.get(String.valueOf(params.get("tableName")))!=null){
					redisColumnMap = redisMap.get(String.valueOf(params.get("tableName")));
				}
				
			}
			columns = sysGeneratorService.queryColumns(String.valueOf(params.get("tableName")));
			for(Map<String,String> map : columns){
				map.put("search", "0");
				map.put("editType", "0");
				map.put("displayList", "0");
				map.put("vaild", "0");
				map.put("vaildValue", "");
				for(Map<String,String> map2 : redisColumnMap){
					if(map.get("COLUMNNAME").equals(map2.get("COLUMNNAME"))){
						map.put("search", map2.get("search"));
						map.put("editType", map2.get("editType"));
						map.put("displayList", map2.get("displayList"));
						map.put("vaild", map2.get("vaild"));
						map.put("vaildValue", map2.get("vaildValue"));
						map.put("assTable", map2.get("assTable"));
						map.put("midAssTable", map2.get("midAssTable"));
						map.put("baseDataType",map2.get("baseDataType"));
					}
				}
				
			}
		}
		PageUtils pageUtil = new PageUtils(columns, 10, 30, 1);
		return R.ok().put("page", pageUtil);
	}
}
